from may import ConfigError
from may import tools
from may.servers import AbstractServers
from may import Server
from may.user import User
from may.module import Module


class YamlFileServers(AbstractServers):
    """this class is for yaml file defined servers list"""

    def __init__(self, yaml_path):
        self.yaml_path = yaml_path
        self.__load__()
        self._init_conn_pool()

    def reload(self):
        self.__load__()

    def __load__(self):
        data = tools.load_yaml(self.yaml_path)
        self.users = {
            user_id: User.create_user(auth="password", **user_params)
            for user_id, user_params in data["users"].items()
        }
        self.modules = {
            module_id: Module.create_module(**module_params)
            for module_id, module_params in data["modules"].items()
        }
        self.servers = self.__load_servers(data["servers"])

    def __load_servers(self, data) -> list:
        user_id = data.pop("user")
        user = self.users.get(user_id)

        server_list = []
        for curtag, sub_node in data.items():
            if isinstance(sub_node, list):
                for host in sub_node:
                    server_list.append(Server(host, user))
            elif tools.is_ipaddress(curtag):
                if sub_node:
                    if sub_node and "user" in sub_node:
                        _user = self.users.get(sub_node.pop("user"))
                        server = Server(curtag, _user, **sub_node)
                    else:
                        server = Server(curtag, user, **sub_node)
                else:
                    server = Server(curtag, user)
                server_list.append(server)
            else:
                _server_list = self.__load_servers(sub_node)
                for server in _server_list:
                    if not server.user:
                        server.user = user
                server_list.extend(_server_list)
        return server_list

    def list_servers(self):
        return self.servers

    def get_servers(self, tag, **kwargs):
        for server in self.servers:
            if server.is_in(tag):
                yield server
